﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

using System.Text;
using System.Xml;
using SdmxMl.Helper;
using SdmxMl.Common;

namespace SdmxMl.GenericData
{
    /// <summary>
    /// The key values at the group level may be stated explicitly, and all which are not 
    /// wildcarded listed in GroupKey - they must also all be given a value at the series level. 
    /// It is not necessary to specify the group key, however, as this may be inferred from the 
    /// values repeated at the series level. If only documentation (group-level attributes) are 
    /// being transmitted, however, the GroupKey cannot be omitted. The type attribute contains 
    /// the name of the declared group in the key family. If any group-level attributes are 
    /// specified in a delete message, then any valid value supplied for the attribute indicates 
    /// that the current attribute value should be deleted for the specified attribute.
    /// </summary>
    public class DataGroupType
    {
        #region Properties

        public DataSetType _datasetOwner;
        public DataSetType DatasetOwner
        {
            get { return _datasetOwner; }
        }


        private string _type;
        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }
        private ValueListTag _groupKey;
        public ValueTypeList GroupKey
        {
            get { return _groupKey.ValueList; }
        }

        private ValueListTag _attributes;
        public ValueTypeList Attributes
        {
            get { return _attributes.ValueList; }
        }

        private SeriesTypeList _seriesList;
        public SeriesTypeList SeriesList
        {
            get { return _seriesList; }
        }

        private AnnotationList annotationList;
        public AnnotationList AnnotationList
        {
            get { return annotationList; }
            set { annotationList = value; }
        }


        #endregion //Properties

        #region Construction
        private void Init()
        {
            AnnotationList = new AnnotationList();
            _seriesList = new SeriesTypeList();
        }

        public DataGroupType(DataSetType owner)
        {
            _datasetOwner = owner;
            Init();
            _groupKey = new ValueListTag("GroupKey");
            _attributes = new ValueListTag("Attributes");
        }

        public DataGroupType(DataSetType owner, XmlNode nodeArtefact, XmlNamespaceManager nsmgr)
        {
            _datasetOwner = owner;
            Init();

            _type = Xmlhelper.GetAtt(nodeArtefact, "type");

            _groupKey = new ValueListTag("GroupKey", nodeArtefact, nsmgr);
            _attributes = new ValueListTag("Attributes", nodeArtefact, nsmgr);
            XmlNodeList nodeList = nodeArtefact.SelectNodes("./generic:Series", nsmgr);
            foreach (XmlNode nm in nodeList)
            {
                SeriesType serie = new SeriesType(nm, nsmgr);
                _seriesList.Add(serie);
            }

            // Annotations
            nodeList = nodeArtefact.SelectNodes("./generic:Annotations/common:Annotation", nsmgr);
            foreach (XmlNode na in nodeList)
            {
                Annotation a = new Annotation(na, nsmgr);
                annotationList.Add(a);
            }
        }

        #endregion //Construction

        #region XML serialize

        public void WriteXml(XmlTextWriter xw, string prefix, string tag)
        {
            xw.WriteStartElement(prefix, tag, null);

            xw.WriteAttributeString("type", _type);
            _groupKey.WriteXml(xw);
            _attributes.WriteXml(xw);

            foreach (SeriesType s in _seriesList)
                s.WriteXml(xw, prefix, "Series");

            // Annotations
            AnnotationList.WriteXml(xw, prefix, null);

            xw.WriteEndElement();
        }


        #endregion //XML serialize

        #region Nodes

        public TreeNode FillNode(TreeNode parentNode)
        {
            TreeNode t = new TreeNode(this.ToString());
            t.Tag = this;
            parentNode.Nodes.Add(t);
            return t;
        }

        #endregion //Nodes

        #region String Representation

        public override string ToString()
        {
            return Type;
        }

        #endregion //String Representation
    }

    public class DataGroupTypeList : List<DataGroupType>
    {
    }
}
